<?php
/**
 * Created by PhpStorm.
 * User: Cianyi
 * Date: 2023/3/31
 * Time: 14:12
 */
namespace Cianyi\Curl;


use think\db\exception\DbException;
use think\exception\ValidateException;
use think\Model;
use think\Request;
use think\Validate;

trait  Curd
{

    /**
     * 可排序字段
     * @var array
     */
    protected $sorts = [];
    /**
     * 可搜索字段
     * @var array
     */
    protected $searchFields = [];
    /**
     * 查询显示字段
     * @var array
     */
    protected $fields = [];

    /**
     * 当前控制器模型
     * @var Model
     */
    protected $model;

    /**
     * 控制器验证类
     * @var Validate
     */
    protected $validate;


    /**
     * 显示资源列表
     * @return \think\response\Json
     * @throws \think\db\exception\DbException
     */
    public function index(Request $request)
    {
        $fieldArr = $this->getFields($request);

        $model  = $this->model->field(is_array($fieldArr) ? implode(",", $fieldArr) : true);
        $wheres = $this->getWheres($request);
        if ($wheres) {
            $model->where($wheres);
        }
        $list = $model->paginate([
            'query'     => [],
            'fragment'  => '',
            'var_page'  => 'page',
            'list_rows' => $this->request->get('pageSize', 10),
        ]);
        return json()->data($list);
    }

    /**
     * @param Request $request
     * @return array
     */
    protected function getFields(Request $request)
    {
        $fieldArr = [];
        if (property_exists($this, "fields") && $this->fields) {
            $fields = $request->get("fields/a", []);
            foreach ($fields as $value) {
                if (in_array($value, $this->fields)) {
                    $fieldArr[] = (string)$value;
                }
            }
        }
        return $fieldArr ? $fieldArr : true;
    }

    /**
     * @param Request $request
     * @return array
     */
    protected function getWheres(Request $request)
    {
        $result = [];
        if (property_exists($this, "searchFields") && $this->searchFields) {
            $searchFields = $request->get("searchFields/a", []);
            foreach ($searchFields as $key => $value) {
                if (in_array($key, $this->searchFields)) {
                    $result[$key] = $value;
                }
            }
        }
        return $result;
    }

    /**
     * 显示创建资源表单页.
     *
     * @return \think\Response
     */
    public function create()
    {
        // TODO: Implement create() method.
    }

    /**
     * 保存新建的资源
     *
     * @param  \think\Request $request
     * @return \think\Response
     */
    public function save(Request $request)
    {
        try {
            $post = $request->post();
            if ($this->validate) {
                $check = $this->validate->scene("save")->check($post);
                if ($check !== true) {
                    throw new  ValidateException($this->validate->getError());
                }
            }
            $model = $this->model->data($post)->save();
            if (!$model) {
                throw new \Exception("error");
            }
        } catch (ValidateException $e) {
            return json()->data(["code" => 4000, "message" => $e->getError()])->code(400);
        } catch (DbException $e) {
            return json()->data(["code" => $e->getCode() ? $e->getCode() : 5001, "message" => "error"])->code(500);
        } catch (\Exception $e) {
            return json()->data(["code" => $e->getCode() ? $e->getCode() : 5000, "message" => $e->getCode() ? $e->getMessage() : "error"])->code(500);
        }
        return json()->data(["code" => 2000, "message" => "success", "data" => $model])->code(200);
    }

    /**
     * 显示指定的资源
     *
     * @param  int $id
     * @return \think\Response
     */
    public function read(Request $request, $id)
    {
        $data = $this->model->field($this->getFields($request))->where(["id" => $id])->select();
        return json()->data(["code" => 2000, "message" => "success", "data" => $data])->code(200);
    }

    /**
     * 显示编辑资源表单页.
     *
     * @param  int $id
     * @return \think\Response
     */
    public function edit(Request $request, $id)
    {
        $data = $this->model->field($this->getFields($request))->find($id);
        return json()->data(["code" => 2000, "message" => "success", "data" => $data])->code(200);
    }

    /**
     * 保存更新的资源
     *
     * @param  \think\Request $request
     * @param  int $id
     * @return \think\Response
     */
    public function update(Request $request, $id)
    {

        try {
            $data = $this->model->field($this->getFields($request))->find($id);
            if (!$data) {
                throw new \Exception("error");
            }
            $post = $request->post();
            if ($this->validate) {
                $check = $this->validate->scene("update")->check($post);
                if ($check !== true) {
                    throw new  ValidateException($this->validate->getError());
                }
            }
            $update = $data->where("id", $id)->save($post);
            if ($update === false) {
                throw new \Exception("error");
            }
        } catch (ValidateException $e) {
            return json()->data(["code" => 4000, "message" => $e->getError()])->code(400);
        } catch (DbException $e) {
            return json()->data(["code" => $e->getCode() ? $e->getCode() : 5000, "message" => "error"])->code(500);
        } catch (\Exception $e) {
            return json()->data(["code" => $e->getCode() ? $e->getCode() : 5000, "message" => $e->getCode() ? $e->getMessage() : "error"])->code(500);
        }
        return json()->data(["code" => 2000, "message" => "success", "data" => $data])->code(200);
    }

    /**
     * 删除指定资源
     *
     * @param  int|array $id
     * @return \think\Response
     */
    public function delete($id)
    {
        $pk = $this->model->getPk();
        $list   = $this->model
            ->field($pk)
            ->where("id", is_array($id) ? "in" : "=", $id)
            ->select();
        $result = [];
        foreach ($list as $value) {
            if ($value->delete()) {
                $result[] = $value[$pk];
            }
        }
        return json()->data(["code" => 2000, "message" => "success","data"=>$result])->code(200);
    }
}